#include "sendpacket.h"

//这个文件实在是太搞笑了，我所做的工作，就是把所有与MD5相关的代码全部删除。联创那帮人太搞笑了，在NNU的客户端中居然完全没有加密算法。
//只是简单的发一些未经加密的包。不同用户之间的区别仅在于往数据包里面填充的用户名和密码的不同，晕死我了！本来以为改这个文件会很辛苦的。

//广播包，用于试探服务器反应。
int SendFindServerPacket(libnet_t *l)
{
	uint8_t broadPackage[0x22] = {        //联创广播包，用于寻找服务器,基于NNU抓包结果修改。
		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8E,0x01,0x01,
		0x00,0x00,0x6C,0x69,0x6E,0x6B,0x61,0x67,0x65,0x00,0x00,0xC8,0x00,0x17,0x00,0x00,
		0x00,0x00};
           
	extern uint8_t  l_localMAC[6];

	memcpy( broadPackage+6, l_localMAC, 6 );   //填充MAC地址

	fputs(">> Searching for server...\n",stdout);

	return (libnet_write_link(l,broadPackage, 0x22)==0x22)?0:-1;
}

//发送用户名
int SendNamePacket(libnet_t *l, const u_char *pkt_data)
{
	extern char *l_name;
	extern uint8_t  l_destMAC[6];
	extern uint8_t  l_localMAC[6];
	int nameLen;
	nameLen=strlen(l_name);//获取用户名长度
	//用了这个很笨的方法区分随园和仙林的用户。
	if (nameLen == 10) {
		static uint8_t ackPackage[0x31] = {        //应答包，用户名
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8E,0x01,0x00,
			0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00};
			const uint8_t pktTail[16] = {0x6C,0x69,0x6E,0x6B,0x61,0x67,0x65,0x00,0x00,0xC8,0x00,0x17,0x00,0x00,0x00,0x00};


	memcpy(ackPackage,l_destMAC,6);  //将目的MAC地址填入组织回复的包
	memcpy(ackPackage+6,l_localMAC,6);  //将本机MAC地址填入组织回复的包

	ackPackage[0x12]=0x02;            //code,2代表应答
	ackPackage[0x13]=pkt_data[0x13];  //ID，与服务器回送包保持一致
	*(short *)(ackPackage+0x10) = htons((short)(5+nameLen));//把用户名长度填入数据包
	*(short *)(ackPackage+0x14) = *(short *)(ackPackage+0x10);//把用户名长度填入数据包
	memcpy(ackPackage+0x17,l_name,nameLen); //填入用户名
	memcpy(ackPackage+0x17+nameLen,pktTail,16); //填入包尾

	fputs(">> Sending user name...\n",stdout);
	
	return (libnet_write_link(l,ackPackage, 0x31)==0x31)?0:-1;
	} 
	else if (nameLen == 12) {
		static uint8_t ackPackage[0x33] = {        //应答包，用户名
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8E,0x01,0x00,
			0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
			0x00,0x00,0x00};
		
		const uint8_t pktTail[16] = {0x6C,0x69,0x6E,0x6B,0x61,0x67,0x65,0x00,0x00,0xC8,0x00,0x17,0x00,0x00,0x00,0x00};


		memcpy(ackPackage,l_destMAC,6);  //将目的MAC地址填入组织回复的包
		memcpy(ackPackage+6,l_localMAC,6);  //将本机MAC地址填入组织回复的包

		ackPackage[0x12]=0x02;            //code,2代表应答
		ackPackage[0x13]=pkt_data[0x13];  //ID，与服务器回送包保持一致
		*(short *)(ackPackage+0x10) = htons((short)(5+nameLen));//把用户名长度填入数据包
		*(short *)(ackPackage+0x14) = *(short *)(ackPackage+0x10);//把用户名长度填入数据包
		memcpy(ackPackage+0x17,l_name,nameLen); //填入用户名
		memcpy(ackPackage+0x17+nameLen,pktTail,16); //填入包尾

		fputs(">> Sending user name...\n",stdout);

		return (libnet_write_link(l,ackPackage, 0x33)==0x33)?0:-1;
	} 
	else {
		fputs("Wrong username, please check /etc/lknnu.conf.\n",stdout);
		return(1);
	}

}

//发送密码
//密码包我不想改了，如果你修改了默认的密码666666，请改回来，或使用任意长度为6字符的密码。
int SendPasswordPacket(libnet_t *l,const u_char *pkt_data)
{
	static uint8_t ackPackage[0x2E] = {        //应答包
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8E,0x01,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x69,
		0x6E,0x6B,0x61,0x67,0x65,0x00,0x00,0xC8,0x00,0x17,0x00,0x00,0x00,0x00};

	extern char *l_password;
	extern uint8_t  l_destMAC[6];
	extern uint8_t  l_localMAC[6];
	int passwordLen;

	passwordLen=strlen(l_password);

	memcpy(ackPackage,l_destMAC,6); //将目的MAC地址填入组织回复的包
	memcpy(ackPackage+6,l_localMAC,6); //将本机MAC地址填入组织回复的包
	memcpy(ackPackage+0x18,l_password,passwordLen);//填入密码

	ackPackage[0x12] = 0x02;                //code,2代表应答
	ackPackage[0x13]=pkt_data[0x13];        //id，与服务器回送包保持一致
	*(ackPackage+0x16) = *(pkt_data+0x16);  //这里就是linkthread.c判断中的那个0x52
	*(short *)(ackPackage+0x10) = htons((short)(passwordLen + 6)); //密码长度+6，不知道用意何在
	*(short *)(ackPackage+0x14) = *(short *)( ackPackage+0x10 ); //填入和上面一样的值
	ackPackage[0x17]=passwordLen;            //在linkage前面填入密码长度

	fputs(">> Sending password... \n",stdout);
	return (libnet_write_link(l,ackPackage, 0x2E)==0x2E)?0:-1;
}

int  SendEndCertPacket(libnet_t *l)
{
	extern uint8_t  l_destMAC[6];
	extern uint8_t  l_localMAC[6];

	static uint8_t ExitPacket[0x22]={
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8E, 0x01, 0x02,
		0x00, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x61, 0x67, 0x65, 0x00, 0x00, 0xC8, 0x00, 0x17, 0x30, 0x00,
		0x00, 0x01};
	memcpy( ExitPacket, l_destMAC, 6);
	memcpy( ExitPacket+6,l_localMAC, 6 );
	fputs(">> Logouting... \n",stderr);
	return (libnet_write_link(l,ExitPacket,0x22)==0x22)?0:-1;
}
